#include "internal.h"

#include <linux/math.h>
#include <linux/jiffies.h>
#include <linux/minmax.h>
#include <linux/softirq.h>

/*
 * Minimal preemption granularity for CPU-bound tasks:
 *
 * (default: 0.75 msec * (1 + ilog(ncpus)), units: nanoseconds)
 */
unsigned int sysctl_sched_base_slice = SCHED_BASE_SLICE;
static unsigned int normalized_sysctl_sched_base_slice	= SCHED_BASE_SLICE;

#define UPDATE_TG	0x0
#define SKIP_AGE_LOAD	0x0
#define DO_ATTACH	0x0
#define DO_DETACH	0x0

#define for_each_sched_entity(se) \
    for (; se; se = NULL)

#define __node_2_se(node) \
    rb_entry((node), struct sched_entity, run_node)

static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
{
    return container_of(cfs_rq, struct rq, cfs);
}

static inline void sched_fair_update_stop_tick(struct rq *rq, struct task_struct *p) {}

#include "fair-numa_balancing.c"
#include "fair-update_misfit_status.c"
#include "fair-hrtick.c"
#include "fair-entity.c"
#include "fair-load_weight.c"
#include "fair-schedstat.c"
#include "fair-est.c"
#include "fair-load_avg.c"
#include "fair-vruntime.c"
#include "fair-slice.c"
#include "fair-smp.c"
#include "fair-bandwidth.c"
#include "fair-group_sched.c"
#include "fair-buddy.c"
#include "fair-update_curr.c"
#include "fair-enqueue_task.c"
#include "fair-dequeue_task.c"
#include "fair-set_next_task.c"
#include "fair-put_prev_task.c"
#include "fair-pick_task.c"
#include "fair-task_tick.c"
#include "fair-wakeup_preempt.c"
#include "fair-switched_to.c"
#include "fair-switched_from.c"
#include "fair-prio_changed.c"
#include "fair-reweight_task.c"
#include "fair-task_dead.c"

#ifdef CONFIG_SMP
#include "fair-balance.c"
#include "fair-select_task_rq.c"
#include "fair-set_cpus_allowed.c"
#endif

static void init_cfs_rq(struct rq *rq)
{
    struct cfs_rq *cfs_rq = &rq->cfs;

    cfs_rq->tasks_timeline = RB_ROOT_CACHED;
    cfs_rq->min_vruntime = (u64)(-(1LL << 20));
}

static void init_sched_fair_class(void)
{
#ifdef CONFIG_SMP
    open_softirq(SCHED_SOFTIRQ, sched_balance_softirq);
#endif
}

/*
 * All the scheduling class methods:
 */
DEFINE_SCHED_CLASS(fair) = {
    .init_class = init_sched_fair_class,
    .init_rq = init_cfs_rq,

    .enqueue_task = enqueue_task_fair,
    .dequeue_task = dequeue_task_fair,

    .pick_task = pick_task_fair,
    .pick_next_task = __pick_next_task_fair,
    .put_prev_task = put_prev_task_fair,
    .set_next_task = set_next_task_fair,

    .task_dead = task_dead_fair,

    .task_tick = task_tick_fair,

	.reweight_task = reweight_task_fair,
	.prio_changed = prio_changed_fair,
	.switched_from = switched_from_fair,
    .switched_to = switched_to_fair,

    .update_curr = update_curr_fair,

    .wakeup_preempt = check_preempt_wakeup_fair,

#ifdef CONFIG_SMP
    .balance = balance_fair,
    .select_task_rq = select_task_rq_fair,
    .set_cpus_allowed = set_cpus_allowed_fair,
#endif
};

void init_fair_entity(struct task_struct *p)
{
    p->se.on_rq = 0;
    p->se.exec_start = 0;
    p->se.sum_exec_runtime = 0;
    p->se.vruntime = 0;
    INIT_LIST_HEAD(&p->se.group_node);
}
